package com.canyou.config;

import de.codecentric.boot.admin.server.config.AdminServerProperties;
import de.codecentric.boot.admin.server.ui.config.AdminServerUiProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.security.web.server.authentication.RedirectServerAuthenticationFailureHandler;
import org.springframework.security.web.server.authentication.RedirectServerAuthenticationSuccessHandler;
import org.springframework.security.web.server.authentication.logout.RedirectServerLogoutSuccessHandler;
import org.springframework.security.web.server.csrf.CookieServerCsrfTokenRepository;
import org.springframework.security.web.server.util.matcher.PathPatternParserServerWebExchangeMatcher;

import java.net.URI;

/**
 * 开启WebFlux的安全认证
 *
 * @author fy
 * @date 2019-05-24 9:22
 */
@EnableWebFluxSecurity
public class SecurityConfig {

    private static final String LOGIN_PATH = "/login";
    private static final String LOGOUT_PATH = "/logout";
    private static final String LOGOUT_SUCCESS_PATH = "/login?logout";
    private static final String LOGIN_FAILURE_PATH = "/login?failed";
    private static final String LOGIN_SUCCESS_PATH = "/#/wallboard";

    @Autowired
    private AdminServerProperties adminServerProperties;

    @Autowired
    private AdminServerUiProperties adminServerUiProperties;

    @Bean
    public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
        final String adminContextPath = adminServerProperties.getContextPath();
        final String proxyPath = adminServerUiProperties.getPublicUrl() != null ?
                "/actuator" : adminContextPath;

        RedirectServerLogoutSuccessHandler redirectServerLogoutSuccessHandler = new RedirectServerLogoutSuccessHandler();
        redirectServerLogoutSuccessHandler.setLogoutSuccessUrl(URI.create(proxyPath + LOGOUT_SUCCESS_PATH));

        return http
                .authorizeExchange()
                .pathMatchers(adminContextPath + LOGIN_PATH, adminContextPath + "/assets/**").permitAll()
                .anyExchange().authenticated()
                .and()
                .formLogin()
                .loginPage(adminContextPath + LOGIN_PATH)
                .authenticationFailureHandler(new RedirectServerAuthenticationFailureHandler(proxyPath + LOGIN_FAILURE_PATH))
                .authenticationSuccessHandler(new RedirectServerAuthenticationSuccessHandler(proxyPath + LOGIN_SUCCESS_PATH))
                .and()
                .logout()
                .logoutUrl(adminContextPath + LOGOUT_PATH)
                .logoutSuccessHandler(redirectServerLogoutSuccessHandler)
                .and()
                .httpBasic()
                .and()
                .csrf()
                .csrfTokenRepository(CookieServerCsrfTokenRepository.withHttpOnlyFalse())
                .requireCsrfProtectionMatcher(new PathPatternParserServerWebExchangeMatcher(adminContextPath + LOGIN_PATH, HttpMethod.POST))
                .disable()
                .build();
    }

}
